#include <cassert>
#include <cstdint>
#include <random>
#include <systemc.h>

template<uint32_t DW>
SC_MODULE(DFF) {
    sc_in<bool>         clock;
    sc_in<bool>         reset_n;
    sc_in<sc_uint<DW>>  din;
    sc_out<sc_uint<DW>> qout;

    void dff_logic() {
        if (!reset_n) {
            qout.write(0);
        } else {
            qout.write(din.read());
        }
    }
    
    SC_CTOR(DFF) {
        SC_METHOD(dff_logic);
        sensitive << clock.pos() << reset_n.neg();
        dont_initialize();
    }
};

int sc_main(int argc, char **argv) {
    const uint32_t DW = 8;
    const uint32_t period = 4;

    sc_clock clock("clock", period, SC_NS);
    sc_signal<bool> reset_n;
    sc_signal<sc_uint<DW>> din, qout;

    DFF<DW> dff("dff");
    dff.clock(clock);
    dff.reset_n(reset_n);
    dff.din(din);
    dff.qout(qout);

    // 随机数生成
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, 0xFF);

    // [波形追踪]
    sc_trace_file *tf = sc_create_vcd_trace_file("dff");
    tf->set_time_unit(1, SC_NS); // 设置时间单位为 1 ns
    sc_trace(tf, clock, "clock");
    sc_trace(tf, reset_n, "reset_n");
    sc_trace(tf, din, "d");
    sc_trace(tf, qout, "q");

    int i = 0;
    // [施加激励]
    reset_n.write(false);
    while (i <= 100) {
        if (i == 13) {
            reset_n.write(true);
        } else if (i == 85) {
            reset_n.write(false);
        }
        if (i % 4 == 3) {
            din.write(dis(gen));
        }
        sc_start(1, SC_NS);
        i++;
    }
    
    sc_close_vcd_trace_file(tf);

    return 0;
}
